/*
 * Copyright (c) 2015-2018 Sfkj Science And Technology Co.,Ltd.
 * All Rights Reserved.
 * This software is the confidential and proprietary information of
 * Sfkj Science And Technology Co.,Ltd.
 * ("Confidential Information").You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Sfkj.
 */
package com.sfkj.walk.command.activity;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.sfkj.walk.api.activity.InviteMemberCommand;
import com.sfkj.walk.api.activity.JoinMemberCommand;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.model.Repository;
import org.axonframework.eventhandling.MetaDataConstants;
import org.axonframework.messaging.annotation.MetaDataValue;
import org.axonframework.queryhandling.QueryGateway;
import org.axonframework.spring.config.AxonConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Service
public class ActivityCommandHandler {

    private final PasswordEncoder passwordEncoder;
    private final QueryGateway queryGateway;
    private final AxonConfiguration axonConfiguration;
    private final CacheManager cacheManager;

    private Repository<Activity> repository;

    @CommandHandler
    public String handle(InviteMemberCommand command) {
        //  生成邀请链接
        Instant now = Instant.now();
        String inviteInfo = Joiner.on(";").join(command.getId(), now.toEpochMilli());
        return Base64.getEncoder().encodeToString(inviteInfo.getBytes());
    }

    @CommandHandler
    public Map<String, String> handle(JoinMemberCommand command, @MetaDataValue(MetaDataConstants.CURRENT_USER_ID) String currentUserId) {
        String invite = command.getInvite();
        List<String> inviteInfo = Splitter.on(";").splitToList(new String(Base64.getDecoder().decode(invite)));

        String id = inviteInfo.get(0);
        Instant inviteInstant = Instant.ofEpochMilli(Long.valueOf(inviteInfo.get(1)));
        Instant now = Instant.now();
        if (!inviteInstant.plus(3, ChronoUnit.DAYS).isAfter(now)) {
            return ImmutableMap.of("id", id, "message", "邀请链接已过期，有效期3天");
        }

        try {
            getRepository().load(id).execute((activity -> activity.joinMember(currentUserId)));
        } catch (Exception e) {
            return ImmutableMap.of("id", id, "message",
                    Objects.equals("用户已经加入该活动", e.getMessage()) ? "您已是该活动成员" : e.getMessage());
        }
        return ImmutableMap.of("id", id, "message", "您加入活动成功");
    }

    public Repository<Activity> getRepository() {
        if (Objects.isNull(repository)) {
            repository = axonConfiguration.repository(Activity.class);
        }
        return repository;
    }
}